<!-- 计划制定 -->
<template>
  <basic-container>
    <div class="informationLabel el-tabs el-tabs--top el-tabs--border-card">
      <div class="el-tabs__header is-top">
        <div class="el-tabs__nav-wrap is-top">
          <div class="el-tabs__nav-scroll">
            <div role="tablist" class="el-tabs__nav is-top" style="transform: translateX(0px)">
              <div id="tab-0" aria-controls="pane-0" role="tab" aria-selected="true" tabindex="0" class="el-tabs__item is-top is-active">计划制定明细</div>
            </div>
          </div>
        </div>
        <div class="el-tabs__content" style="padding: 10px 10px 0 10px; background-color: #ffffff">
          <el-table
            ref="crud"
            height="calc(100vh - 200px)"
            v-loading="loading"
            size="mini"
            :data="data"
            border="1"
            empty-text=" "
            :span-method="spanMethod"
            :cell-class-name="tableCellClassName"
            @cell-mouse-enter="cellMouseEnter"
          >
            <el-table-column prop="workshopName" label="车间"> </el-table-column>
            <el-table-column prop="lineName" label="产线"> </el-table-column>
            <el-table-column v-for="(item, index) in workDayList" :key="index" :prop="item" :label="item">
              <template slot-scope="{ row }" v-if="popoverShow && row.detailVOList && row.detailVOList.length > 0">
                <el-popover placement="right" width="900" trigger="hover">
                  <div class="menu">
                    <!-- 撤销排程 -->
                    <el-button size="small" icon="el-icon-back" @click="handleMenu({ type: 'startSchedule', row })">撤销排程</el-button>
                    <!-- 生产完成 -->
                    <el-button type="primary" size="small" icon="el-icon-finished" @click="handleMenu({ type: 'editSchedule', row })">生产完成</el-button>
                  </div>
                  <el-table :data="gridData" border="1">
                    <el-table-column width="150" property="productionOrderNo" label="生产订单"></el-table-column>
                    <el-table-column property="planQuantity" label="订单数量"></el-table-column>
                    <el-table-column width="150" property="workOrderNo" label="工单"></el-table-column>
                    <el-table-column property="planQuantity" label="工单数量"></el-table-column>
                    <el-table-column width="160" property="planStartDate" label="计划开始时间"></el-table-column>
                    <el-table-column width="160" property="planEndDate" label="计划结束时间"></el-table-column>
                    <el-table-column width="80" property="status" label="状态">
                      <template slot-scope="{ row }">
                        <span v-if="row.status == 1" style="color: #e6a23c">{{ workOrderStatus[0] }}</span>
                        <span v-if="row.status == 2" style="color: #409eff">{{ workOrderStatus[1] }}</span>
                      </template>
                    </el-table-column>
                  </el-table>
                  <div class="table-hover-hidden" slot="reference">{{ index }}</div>
                </el-popover>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
  </basic-container>
</template>

<script>
import { getGanttChart, cancelGantt, finishGantt } from '@/api/aps/workPlan';
import globalModalTemplate from '@/components/common-modal-template/global-modal-template.vue';
import { mapGetters } from 'vuex';
export default {
  components: {
    globalModalTemplate
  },
  inject: ['reload'],
  data() {
    return {
      //  待下发：1， 已下发：2
      workOrderStatus: ['待下发', '已下发'],
      popoverShow: false,
      gridData: [],
      productionOrderNoList: [], // 订单号列表
      workDayList: [],
      hoverCellIndex: null, // hover单元格列索引
      loading: true,
      data: []
    };
  },
  computed: {
    ...mapGetters(['permission']),
    permissionList() {
      return {
        // addBtn: this.vaildData(this.permission.workorder_add, false),
        // viewBtn: this.vaildData(this.permission.workorder_view, false),
        // delBtn: this.vaildData(this.permission.workorder_delete, false),
        // editBtn: this.vaildData(this.permission.workorder_edit, false)
      };
    }
  },
  mounted() {
    this.onLoad();
  },
  watch: {
    $route: {
      handler(value) {
        this.reload();
      }
    }
  },
  methods: {
    // 从一开始，因为scss for循环定义的类是从1开始
    // 给单元格加class class ：row-1:行号1 productionOrderNo-1:订单号-1 columnIndex:列索引 productionOrderNo：订单号 custom-order-0
    tableCellClassName({ row, column, rowIndex, columnIndex }) {
      if (row && row.detailVOList && row.detailVOList.length > 0) {
        if (columnIndex !== 0 && columnIndex !== 1 && column.property) {
          let rowNum = null,
            columnNum = null;
          let detailVOList = row.detailVOList;
          if (detailVOList[0] && columnIndex == detailVOList[0].startDayIndex) {
            let productionOrderNoIndex = this.productionOrderNoList.findIndex((product) => product.productionOrderNo == row.detailVOList[0].productionOrderNo);
            let productionOrderNo = this.productionOrderNoList[productionOrderNoIndex].productionOrderNo;
            rowNum = rowIndex; // 行号
            columnNum = productionOrderNoIndex; // 订单号
            return `row-${rowNum + 1} productionOrderNo-${columnNum + 1} columnIndex-${columnIndex} ${productionOrderNo} custom-order-0`;
          }

          if (detailVOList[1] && columnIndex == detailVOList[0].startDayIndex + detailVOList[1].startDayIndex - detailVOList[0].endDayIndex) {
            let productionOrderNoIndex = this.productionOrderNoList.findIndex((product) => product.productionOrderNo == row.detailVOList[1].productionOrderNo);
            let productionOrderNo = this.productionOrderNoList[productionOrderNoIndex].productionOrderNo;
            rowNum = rowIndex; // 行号
            columnNum = productionOrderNoIndex; // 订单号
            return `row-${rowNum + 1} productionOrderNo-${columnNum + 1} columnIndex-${columnIndex} ${productionOrderNo} custom-order-1`;
          }
          if (detailVOList[2] && columnIndex == detailVOList[1].startDayIndex + detailVOList[2].startDayIndex - detailVOList[1].endDayIndex - 1) {
            let productionOrderNoIndex = this.productionOrderNoList.findIndex((product) => product.productionOrderNo == row.detailVOList[2].productionOrderNo);
            let productionOrderNo = this.productionOrderNoList[productionOrderNoIndex].productionOrderNo;
            rowNum = rowIndex; // 行号
            columnNum = productionOrderNoIndex; // 订单号
            return `row-${rowNum + 1} productionOrderNo-${columnNum + 1} columnIndex-${columnIndex} ${productionOrderNo} custom-order-2`;
          }
        }
      }
    },
    // 合并行和列 retrurn rowspan行数 colspan列数
    spanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex !== 0 && columnIndex !== 1) {
        if (row.detailVOList && row.detailVOList.length > 0) {
          let detailVOList = row.detailVOList;
          if (detailVOList[0] && columnIndex == detailVOList[0].startDayIndex) {
            return [1, detailVOList[0].gap];
          }
          if (detailVOList[1] && columnIndex == detailVOList[0].startDayIndex + detailVOList[1].startDayIndex - detailVOList[0].endDayIndex) {
            return [1, detailVOList[1].gap];
          }
          if (detailVOList[2] && columnIndex == detailVOList[1].startDayIndex + detailVOList[2].startDayIndex - detailVOList[1].endDayIndex - 1) {
            return [1, detailVOList[2].gap];
          }
        } else {
          return [1, this.workDayList.length];
        }
      }

      const span = column['property'] + '-span';
      if (row[span]) {
        return row[span];
      }
    },
    handleMenu(params) {
      let { type, row } = params;
      let name = '';
      switch (type) {
        case 'startSchedule':
          this.$confirm(`确定撤销订单号${this.gridData[0].productionOrderNo}的排程?`, {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              cancelGantt({
                planId: this.gridData[0].productionPlanId
              }).then(() => {
                this.$message.success('撤销排程成功');
                this.onLoad();
              });
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '撤销排程已取消'
              });
            });
          return;
        case 'editSchedule':
          let workOrderData = this.gridData[0];
          this.$confirm(`确定将工单号${workOrderData.workOrderNo}结束生产?`, {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              // 同订单单号的单元格Dom集合
              let allProductionOrderNoDom = document.querySelectorAll(`.${workOrderData.productionOrderNo}`),
                allProductionOrderNoDomLength = allProductionOrderNoDom.length;
              let ProductionOrderNoIndexs = [];
              if (allProductionOrderNoDomLength > 1) {
                allProductionOrderNoDom.forEach((dom) => {
                  dom.classList.forEach((list) => {
                    if (list.startsWith('columnIndex-')) {
                      let index = Number(list.split('columnIndex-')[1]);
                      ProductionOrderNoIndexs.push(index);
                    }
                  });
                });
                ProductionOrderNoIndexs.sort((a, b) => a - b);
                if (this.hoverCellIndex == ProductionOrderNoIndexs[0]) {
                  finishGantt({
                    detailId: workOrderData.id
                  }).then(() => {
                    this.$message.success('结束生产成功');
                    this.onLoad();
                  });
                } else {
                  this.$message.warning('当前订单下存在多个工单，请先结束生产第一个工单');
                  return;
                }
              } else {
                finishGantt({
                  detailId: workOrderData.id
                }).then(() => {
                  this.$message.success('结束生产成功');
                  this.onLoad();
                });
              }
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '结束生产已取消'
              });
            });
          return;
        default:
          break;
      }
    },
    onLoad() {
      this.loading = true;
      getGanttChart().then((res) => {
        if (res && res.data.data) {
          let result = res.data.data;
          let data = result.detailDeptVOList;
          let that = this;
          this.workDayList = result.workDayList.sort((a, b) => {
            return a > b ? 1 : -1;
          });
          // 时间排序
          this.data = [];
          this.productionOrderNoList = [];
          // 重组数据
          data.map((d) => {
            if (d.lineList && d.lineList.length > 0) {
              this.data = this.data.concat(d.lineList);
            } else {
              this.data = this.data.concat(d);
            }
          });
          this.data = this.mergeTableRow(this.data, ['workshopName']);
          this.data.map((d, i) => {
            this.workDayList.map((day) => {
              d[day] = '';
            });
            if (d.detailVOList && d.detailVOList.length > 0) {
              d.detailVOList = d.detailVOList
                .map((detail) => {
                  let calendarStartDate = detail.calendarStartDate.substr(0, 10);
                  let calendarEndDate = detail.calendarEndDate.substr(0, 10);
                  let startDayIndex = this.workDayList.findIndex((work) => work == calendarStartDate);
                  let endDayIndex = this.workDayList.findIndex((work) => work == calendarEndDate);
                  if (startDayIndex > -1) {
                    startDayIndex = startDayIndex + 2;
                  } else {
                    // 在生产日历中查找距离数据开始时间最近的日期
                    function searchCorrectDay(day) {
                      let dayList = that.workDayList.filter((work) => work < day);
                      if (dayList && dayList.length > 0) {
                        let recentlyDay = dayList.at(-1);
                        let isCorrectDay = that.workDayList.findIndex((work) => work == recentlyDay);
                        if (isCorrectDay == -1) {
                          searchCorrectDay(recentlyDay);
                        }
                        return isCorrectDay;
                      }
                    }
                    let correctDay = searchCorrectDay(calendarStartDate);
                    startDayIndex = correctDay + 2;
                  }
                  if (endDayIndex > -1) {
                    endDayIndex = endDayIndex + 2;
                  } else {
                    // 在生产日历中查找距离数据结束时间最近的日期
                    function searchCorrectDay(day) {
                      let dayList = that.workDayList.filter((work) => work < day);
                      let isCorrectDay = null;
                      if (dayList && dayList.length > 0) {
                        let recentlyDay = dayList.at(-1);
                        isCorrectDay = that.workDayList.findIndex((work) => work == recentlyDay);
                        if (isCorrectDay == -1) {
                          searchCorrectDay(recentlyDay);
                        }
                      }
                      return isCorrectDay;
                    }
                    let correctDay = searchCorrectDay(calendarEndDate);
                    endDayIndex = correctDay + 2;
                  }
                  return {
                    calendarStartDate,
                    calendarEndDate,
                    startDayIndex,
                    endDayIndex,
                    gap: endDayIndex - startDayIndex + 1,
                    productionOrderNo: detail.planSimpleVO.productionOrderNo,
                    ...detail
                  };
                })
                .sort((a, b) => {
                  return a.startDayIndex - b.startDayIndex;
                });
            }
            return d;
          });
          // 获取所有生产订单号集合
          this.data.map((d) => {
            if (d.detailVOList && d.detailVOList.length > 0) {
              d.detailVOList.map((detail) => {
                let find = this.productionOrderNoList.find((product) => product.productionOrderNo == detail.productionOrderNo);
                if (!find) {
                  this.productionOrderNoList.push({ productionOrderNo: detail.productionOrderNo, productionPlanId: detail.productionPlanId });
                }
              });
            }
          });
          this.data.map((d, i) => {
            if (d.detailVOList && d.detailVOList.length > 0) {
              if (d.detailVOList[1] && d.detailVOList[1].startDayIndex <= d.detailVOList[0].endDayIndex) {
                d.detailVOList[1].startDayIndex = d.detailVOList[0].endDayIndex + 1;
                d.detailVOList[1].gap = d.detailVOList[1].endDayIndex - d.detailVOList[1].startDayIndex + 1;
              }
              if (d.detailVOList[2] && d.detailVOList[2].startDayIndex <= d.detailVOList[1].endDayIndex) {
                d.detailVOList[2].startDayIndex = d.detailVOList[1].endDayIndex + 1;
                d.detailVOList[2].gap = d.detailVOList[2].endDayIndex - d.detailVOList[2].startDayIndex + 1;
              }
            }
          });
          this.loading = false;
        }
      });
    },
    // 根据条件合并行
    mergeTableRow(data, merge) {
      if (!merge || merge.length === 0) {
        return data;
      }
      merge.forEach((m) => {
        const mList = {};
        data = data.map((v, index) => {
          const rowVal = v[m];
          if (mList[rowVal] && mList[rowVal].newIndex === index) {
            mList[rowVal]['num']++;
            mList[rowVal]['newIndex']++;
            data[mList[rowVal]['index']][m + '-span'].rowspan++;
            v[m + '-span'] = {
              rowspan: 0,
              colspan: 0
            };
          } else {
            mList[rowVal] = { num: 1, index: index, newIndex: index + 1 };
            v[m + '-span'] = {
              rowspan: 1,
              colspan: 1
            };
          }
          return v;
        });
      });
      return data;
    },
    cellMouseEnter(row, column, cell, event) {
      if (row.detailVOList && row.detailVOList.length > 0) {
        this.popoverShow = true;
        let vaildHover = cell.className.indexOf('productionOrderNo-') > -1;
        if (vaildHover) {
          for (let i = 0; i < cell.classList.length; i++) {
            if (cell.classList[i].startsWith('columnIndex-')) {
              this.hoverCellIndex = Number(cell.classList[i].split('columnIndex-')[1]);
            }
          }
          let productionOrderNoClass = cell.className.split('custom-order-');
          let orderSerialNum = productionOrderNoClass[1];
          let orderData = row.detailVOList[orderSerialNum];
          this.gridData = [
            {
              productionOrderNo: orderData.productionOrderNo,
              planQuantity: orderData.planQuantity,
              workOrderNo: orderData.workOrderNo,
              planQuantity: orderData.planQuantity,
              planStartDate: orderData.planStartDate,
              planEndDate: orderData.planEndDate,
              status: orderData.status,
              productionPlanId: orderData.productionPlanId,
              id: orderData.id
            }
          ];
          this.popoverShow = true;
        } else {
          this.popoverShow = false;
        }
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.basic-container {
  height: calc(100vh - 120px);
  ::v-deep .basic-container__card {
    height: 100%;
    .el-card__body {
      height: 100%;
    }
  }
}
.menu {
  margin-bottom: 10px;
}
.table-hover-hidden {
  color: #fff0;
  overflow: hidden;
}
::v-deep .el-table__row {
  $colors: #ffb7dd, #ff88c2, #ff44aa, #ff0088, #c10066, #a20055, #8c0044, #ffcccc, #ff8888, #ff3333, #ff0000, #cc0000, #aa0000, #880000, #ffc8b4, #ffa488, #ff7744, #ff5511,
    #e63f00, #c63300, #a42d00, #ffddaa, #ffbb66, #ffaa33, #ff8800, #ee7700, #cc6600, #bb5500, #ffee99, #ffdd55, #ffcc22, #ffbb00, #ddaa00, #aa7700, #886600, #ffffbb, #ffff77,
    #ffff33, #ffff00, #eeee00, #bbbb00, #888800, #eeffbb, #ddff77, #ccff33, #bbff00, #99dd00, #88aa00, #668800, #ccff99, #bbff66, #99ff33, #77ff00, #66dd00, #55aa00, #227700,
    #99ff99, #66ff66, #33ff33, #00ff00, #00dd00, #00aa00, #008800, #bbffee, #77ffcc, #33ffaa, #00ff99, #00dd77, #00aa55, #008844, #aaffee, #77ffee, #33ffdd, #00ffcc, #00ddaa,
    #00aa88, #008866, #99ffff, #66ffff, #33ffff, #00ffff, #00dddd, #00aaaa, #008888, #cceeff, #77ddff, #33ccff, #00bbff, #009fcc, #0088a8, #007799, #ccddff, #99bbff, #5599ff,
    #0066ff, #0044bb, #003c9d, #003377, #ccccff, #9999ff, #5555ff, #0000ff, #0000cc, #0000aa, #000088, #ccbbff, #9f88ff, #7744ff, #5500ff, #4400cc, #2200aa, #220088, #d1bbff,
    #b088ff, #9955ff, #7700ff, #5500dd, #4400b3, #3a0088, #e8ccff, #d28eff, #b94fff, #9900ff, #7700bb, #66009d, #550088, #f0bbff, #e38eff, #e93eff, #cc00ff, #a500cc, #7a0099,
    #660077, #ffb3ff, #ff77ff, #ff3eff, #ff00ff, #cc00cc, #990099, #770077;

  @each $c in $colors {
    $i: index($colors, $c);
    .row-#{$i} {
      background: rgba($c, 0.5);
    }
    $a: index($colors, $c);
    .productionOrderNo-#{$a} {
      background: rgba($c, 1) !important;
    }
  }
}
</style>
